package tul.cot.util;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;

import tul.cot.io.PlotPoint;
import tul.cot.job.Migrations;


public class HistogramAggregator {

	private static final String NO_LABEL = null;
	public static final double DUMMY_DAI_VALUE = -100;
	
//	private final int NUM_TREES;
	private final int NUM_BUCKETS;
	private DescriptiveStatistics stats = new DescriptiveStatistics();
	private String currLabel = NO_LABEL;
	
	private List<Histogram> histograms = new ArrayList<Histogram>();
	
	public HistogramAggregator(int numBuckets) {
		NUM_BUCKETS = numBuckets;
	}
	
	public List<Histogram> getHistograms() {
		return histograms;
	}
	
	public void aggregate(Iterable<PlotPoint> values) {
		for (PlotPoint pp: values) {
			add(pp);
		}
		
		aggregateHistogram();
	}

	private void aggregateHistogram() {
		double mean = stats.getMean();
		double[] values = stats.getValues();
		if (mean != Double.NaN && mean < 0) {
			currLabel = oppositeLabel(currLabel);
			for (int x=0; x<values.length; ++x) {
				values[x] = -values[x];
			}
		}
		
		Histogram hist = new Histogram(currLabel, -1, 1, NUM_BUCKETS);
		hist.addValues(values);
		
		histograms.add(hist);
	}

	private String oppositeLabel(String label) {
		String[] split = label.split(Migrations.PAIR_SEP);
		String from = split[0];
		String to = split[1];
		
		String oppLabel = String.format("%s%s%s", to, Migrations.PAIR_SEP, from);
		return oppLabel;
	}

	private void add(PlotPoint pp) {
		if (!pp.getLabel().equals(currLabel)) {
			if (currLabel != NO_LABEL) {
				aggregateHistogram();
			}
			startNewLabel(pp);
		}
		
		addValue(pp);
	}
	
	private void startNewLabel(PlotPoint pp) {
		stats.clear();
		currLabel = pp.getLabel();
	}
	
	private void addValue(PlotPoint pp) {
		double value = pp.getValue();
		
		if (value != DUMMY_DAI_VALUE)
			stats.addValue(value);
	}
}
